home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Networking / OT⁄PPP Control Strip Sample / PPP Control.cp < prev    next >
Encoding:
Text File  |  2000-09-28  |  16.0 KB  |  574 lines  |  [TEXT/CWIE]

  1. /*************************************************************************
  2. **    Apple Macintosh Developer Technical Support
  3. **
  4. **    PPP Control strip Module
  5. **
  6. **    by Vinne Moscaritolo, <vinnie@apple.com>
  7. **    Apple Developer Technical Support 
  8. **
  9. **  Created from as much sample code I could find.
  10. **  " Good Artists Imitate, Great Artist Steal "
  11. **
  12. **    File:        PPP Control.cp
  13. **
  14. **    Copyright © 1996 Apple Computer, Inc.
  15. **    All rights reserved.
  16. **
  17. **    You may incorporate this sample code into your applications without
  18. **    restriction, though the sample code has been provided "AS IS" and the
  19. **    responsibility for its operation is 100% yours.  However, what you are
  20. **    not permitted to do is to redistribute the source as "DSC Sample Code"
  21. **    after having made changes. If you're going to re-distribute the source,
  22. **    we require that you make it clear in the source that the code was
  23. **    descended from Apple Sample Code, but that you've made changes.
  24. **
  25. **************************************************************************/
  26.  
  27.  
  28.  
  29. //------------------------------------------------------------------------------------
  30. #pragma mark Includes
  31. //------------------------------------------------------------------------------------
  32.  
  33. #include <Exception.h>
  34. #include <A4Stuff.h>
  35.  
  36. #include <ControlStrip.h>
  37. #include <OpenTransport.h>
  38.  
  39. #include "OpenTptPPP.h"                // Hopefully this will be in the univeral someday
  40.  
  41.  
  42. //------------------------------------------------------------------------------------
  43. #pragma mark Defines
  44. //------------------------------------------------------------------------------------
  45.  
  46. #define USES_ASYNC_OPENS     0
  47.  
  48. #define kPPPCreator            'rmot'
  49. #define kModemCreator        'modm'
  50. #define kControlPanelType    'cdev'
  51.  
  52. #define    kBaseIconID            129                
  53. #define    kPopupArrowPictID    256
  54. #define    kMenuID                256
  55.  
  56. enum {     kPPPLoaded = 0 ,
  57.         kPPPNotLoaded, 
  58.         kPPPFailed, 
  59.         kPPPOpen };
  60.  
  61. #define    mOpenPPPCP            1
  62. #define    mOpenModemCP        2
  63.  
  64. #define    mDisconnect            4
  65. #define    mSomethig            5
  66.  
  67. #define    IconWidth            16
  68.  
  69. #define MAX_ICONS 4
  70.  
  71. #define ThrowIfNil( _val_ )        \
  72.         if ( (_val_) == nil )    \
  73.             throw
  74.  
  75. #define ThrowIfNotNil( _val_ )    \
  76.         if ( (_val_) != nil )    \
  77.             throw
  78.  
  79. #define ThrowIfOSErr(_err_)            \
  80.         if ((_err_) != noErr)        \
  81.             throw 
  82.  
  83. #define ThrowOSErr(_err_)        \
  84.             throw
  85.  
  86. long GetCurrentA5(void):__D0     = 0x200D;    /* move.l    A5,D0        */
  87. long SetA5(long:__D0):__D0         = 0xC18D;    /* EXG      D0,A5        */
  88. void SyncA5fromA4(void)            = 0x2A4C;    /* move.l     A4,A5        */
  89.  
  90. //------------------------------------------------------------------------------------
  91. #pragma mark Prototypes
  92. //------------------------------------------------------------------------------------
  93. void OpenControlPanel    (OSType folder, OSType fdCreator, OSType  fdType);
  94.  
  95.  
  96. //------------------------------------------------------------------------------------
  97. #pragma mark -
  98.  
  99.  
  100. //------------------------------------------------------------------------------------
  101. #pragma mark class CSM
  102. //------------------------------------------------------------------------------------
  103.  
  104. class CSM {
  105.  
  106. public:
  107.          CSM();
  108.         ~CSM();
  109.         
  110.     long GetDisplayWidth    ();
  111.     long Periodic            (Rect *, GrafPtr);
  112.     long Draw                (Rect *, GrafPtr);
  113.     long MouseDown            (Rect *, GrafPtr);
  114.     long SaveSettings        ();
  115.     long ShowBalloonHelp    ();
  116.  
  117.     static pascal void NotifyProc(CSM*, OTEventCode, OTResult, void*);
  118.  
  119. private:
  120.     Boolean UpdateStatus    ();
  121.     
  122. protected:
  123.         Handle            fIcons[MAX_ICONS];
  124.         MenuHandle        fMenu;            
  125.         PicHandle        fPopupArrowPicture;    
  126.         EndpointRef        fEndPoint;
  127.         unsigned long    fPPPState;
  128.         short            fCurrentIcon;        
  129.         short            fState;
  130. };
  131.  
  132. //------------------------------------------------------------------------------------
  133. CSM::CSM()
  134. //------------------------------------------------------------------------------------
  135. {
  136.     short     i;
  137.     long    response;
  138.  
  139. //    OpenTransport Must be present
  140.     ThrowIfOSErr (::Gestalt(gestaltOpenTpt, &response));
  141.     if (! (response & (1 << gestaltOpenTptPresentBit)))  throw;
  142.  
  143. //    OpenTransport/ Remote Access must also be present
  144.     ThrowIfOSErr (::Gestalt(gestaltOpenTptRemoteAccess, &response));
  145.     if (!(response & (1 << gestaltOpenTptRemoteAccessPresent)))  throw;
  146.  
  147. //    OpenTransport/ Remote Access PPP must also be present
  148.     if (! (response & (1 << gestaltOpenTptPPPPresent))) throw;
  149.     
  150. //    load and detach the icon suites
  151.     for(i = 0; i < MAX_ICONS; i++)
  152.         ThrowIfOSErr( ::SBGetDetachIconSuite(&fIcons[i], kBaseIconID+i, svAllSmallData));
  153.  
  154. //    load and detach the configuration menu
  155.     ThrowIfNil (fMenu = ::GetMenu(kMenuID) );
  156.     ::DetachResource((Handle)fMenu);
  157.  
  158. //    load and detach the ‘up arrow’ picture
  159.     ThrowIfNil (fPopupArrowPicture = ::GetPicture(kPopupArrowPictID) );
  160.     ::DetachResource((Handle)fPopupArrowPicture);
  161.  
  162.     fState         = kPPPNotLoaded;
  163.     fPPPState    = -1;
  164.     fEndPoint    = kOTInvalidEndpointRef;
  165.     
  166.     {
  167.         long     old_A5 = GetCurrentA5();
  168.         SyncA5fromA4();
  169.  
  170. //    Initialize OT
  171.         if (InitOpenTransport()!= kOTNoError) fState  = kPPPFailed;
  172.         
  173.         (void) SetA5(old_A5);
  174.     }
  175.         
  176. }
  177.  
  178.  
  179. //------------------------------------------------------------------------------------
  180. CSM::~CSM()
  181. //------------------------------------------------------------------------------------
  182. {
  183. // don't forget to write this
  184. };
  185.     
  186. //------------------------------------------------------------------------------------
  187. long CSM::GetDisplayWidth()
  188. //------------------------------------------------------------------------------------
  189. {
  190.     return (IconWidth +
  191.                 (**fPopupArrowPicture).picFrame.right - (**fPopupArrowPicture).picFrame.left);
  192. }
  193.  
  194. //------------------------------------------------------------------------------------
  195. long CSM::Periodic(Rect *theRect, GrafPtr thePort)
  196. //------------------------------------------------------------------------------------
  197. {
  198.     if( !UpdateStatus() ) return 0;
  199.     
  200.     theRect->right = theRect->left + IconWidth;
  201.     ::EraseRect(theRect);                        
  202.     Draw(theRect,thePort);
  203.     
  204.     return  1<<sdevHelpStateChange;
  205. }
  206.  
  207. //------------------------------------------------------------------------------------
  208. long CSM::Draw(Rect *theRect, GrafPtr thePort)
  209. //------------------------------------------------------------------------------------
  210. {    
  211.     short    arrowHeight;
  212.  
  213. //    draw the current icon
  214.     theRect->right = theRect->left + IconWidth;
  215.     (void) ::PlotIconSuite(theRect, atNone, ttNone, fIcons[fState] );
  216.  
  217. //    draw an ‘up arrow’ to show that the module has a popup menu
  218.     arrowHeight = (**fPopupArrowPicture).picFrame.bottom - (**fPopupArrowPicture).picFrame.top;
  219.     theRect->left = theRect->right;
  220.     theRect->right += (**fPopupArrowPicture).picFrame.right - (**fPopupArrowPicture).picFrame.left;
  221.     theRect->top = (theRect->top + theRect->bottom - arrowHeight) >> 1;
  222.     theRect->bottom = theRect->top + arrowHeight;
  223.     ::DrawPicture(fPopupArrowPicture, theRect);
  224.     
  225.     return 0;
  226. }
  227.  
  228. //------------------------------------------------------------------------------------
  229. long CSM::MouseDown(Rect *theRect, GrafPtr thePort)
  230. //------------------------------------------------------------------------------------
  231. {
  232.     short            menuItem;
  233.     long            result;
  234.  
  235.     menuItem = SBTrackPopupMenu(theRect, fMenu);
  236.     result = 0;
  237.  
  238.     switch (menuItem){
  239.         case mOpenPPPCP:
  240.                 OpenControlPanel(kControlPanelFolderType,kPPPCreator, kControlPanelType);
  241.             break;
  242.  
  243.         case mOpenModemCP:
  244.                 OpenControlPanel(kControlPanelFolderType,kModemCreator, kControlPanelType);
  245.             break;
  246.                 
  247.         case mDisconnect:
  248.                 DebugStr((ConstStr255Param)"/pPPP Disconnect");
  249.             break;
  250.     }
  251.  
  252.     return(result);
  253. }
  254.  
  255. //------------------------------------------------------------------------------------
  256. long CSM::SaveSettings()
  257. //------------------------------------------------------------------------------------
  258. {
  259.     return 0;
  260. }
  261.  
  262. //------------------------------------------------------------------------------------
  263. long CSM::ShowBalloonHelp()
  264. //------------------------------------------------------------------------------------
  265. {
  266.     return 0;
  267. }
  268.  
  269.  
  270. //------------------------------------------------------------------------------------
  271. Boolean CSM::UpdateStatus()
  272. //------------------------------------------------------------------------------------
  273. //
  274. // rwrite this uglyness with a real state machine...
  275. //
  276. {    
  277.  
  278.     switch(fState)
  279.         {
  280.             case kPPPNotLoaded:
  281.                 {
  282.  
  283. // first check to see if PPP got loaded yet.
  284.                     long    response;
  285.                     ::Gestalt(gestaltOpenTptRemoteAccess, &response);
  286.                     if (!(response & (1 << gestaltOpenTptRemoteAccessLoaded))) return false;
  287.                     
  288.                         fState = kPPPLoaded;
  289.                     
  290.                     {
  291.                     long     old_A5 = GetCurrentA5();
  292.                     SyncA5fromA4();
  293.             
  294. // maybe there is a bug in the configuartor, 
  295. // that wont allow openasyncs on the first endpoint.
  296.  
  297. #if USES_ASYNC_OPENS
  298.  
  299. //        DebugStr("\p CSM::UpdateStatus - OTAsyncOpenEndpoint");        
  300.                     if( ::OTAsyncOpenEndpoint( OTCreateConfiguration(kPPPControlName),0, nil,(OTNotifyProcPtr) NotifyProc, this )
  301.                          != kOTNoError) fState = kPPPFailed;
  302. #else
  303.                     OTResult result;
  304. //        DebugStr("\p CSM::UpdateStatus - OTOpenEndpoint");        
  305.                     
  306.                     fEndPoint = ::OTOpenEndpoint(OTCreateConfiguration(kPPPControlName),0, nil, &result); 
  307.                     if( (result == kOTNoError) && (fEndPoint != kOTInvalidEndpointRef))
  308.                         if( (result = fEndPoint->InstallNotifier((OTNotifyProcPtr) NotifyProc, (void*) this)) == kOTNoError) 
  309.                             {    
  310. //                                fState = kPPPOpen;
  311.                                 OTSetAsynchronous(fEndPoint);
  312.                                 if( ::OTIoctl(fEndPoint, I_OTGetMiscellaneousEvents, (void*)1) != kOTNoError ) fState = kPPPFailed;
  313.                             } 
  314. #endif                    
  315.                     (void) SetA5(old_A5);
  316.                     }
  317.                 }
  318.                 return true;
  319.             
  320.             case kPPPLoaded:
  321.             case kPPPFailed:
  322.                 return false;
  323.             
  324.             case kPPPOpen:
  325.     
  326. //                    PPP_OPT_GETCURRENTSTATE fPPPState
  327. //                    OTOptionManagement(fEndPoint,Cmd,Ret)
  328.                     
  329.                 return true;
  330.     }
  331.     return false;
  332.         
  333. }
  334.  
  335.  
  336. //------------------------------------------------------------------------------------
  337. pascal void CSM::NotifyProc(CSM* csm, OTEventCode code, OTResult result, void* cookie)
  338. //------------------------------------------------------------------------------------
  339. {
  340.     long     old_A4 = SetCurrentA4();
  341. //    long     old_A5 = GetCurrentA5();
  342. //    SyncA5fromA4();
  343.  
  344.     switch(code)
  345.     {
  346. // Endpoint opened
  347.         case T_OPENCOMPLETE:
  348.             csm->fState = kPPPFailed;
  349.  
  350.             if(result != kOTNoError)
  351.                 DebugStr("\p CSM::NotifyProc - T_OPENCOMPLETE Failed; d3.w; ");
  352.             
  353. //if(result == kOTAccessErr) DebugStr("\p CSM::NotifyProc - Missing access permission");
  354.             if(result != kOTNoError) break;
  355.             
  356.              csm->fEndPoint = (EndpointRef) cookie;
  357.  
  358. // ask PPP for misc events
  359.             if( ::OTIoctl(csm->fEndPoint, I_OTGetMiscellaneousEvents, (void*)1) != kOTNoError ) break;
  360.             csm->fState = kPPPOpen;
  361.              break;
  362.  
  363.         case kStreamIoctlEvent:
  364.                 if(result != kOTNoError){
  365.                         DebugStr("\p PPP CSM::NotifyProc -  kStreamIoctlEvent");
  366.                         csm->fState = kPPPFailed;
  367.                         break;
  368.                         };
  369.                 csm->fState = kPPPOpen;
  370.  
  371.             break;
  372.             
  373.         case T_OPTMGMTCOMPLETE:
  374.             break;
  375.         
  376. // PPP events
  377.         case kPPPConnectCompleteEvent:
  378.         case kPPPSetScriptCompleteEvent    :
  379.         case kPPPDisconnectCompleteEvent:
  380.         case kPPPDisconnectEvent:
  381.         case kPPPIPCPUpEvent:
  382.         case kPPPIPCPDownEvent:
  383.         case kPPPLCPUpEvent:
  384.         case kPPPLCPDownEvent:
  385.         case kPPPLowerLayerUpEvent:
  386.         case kPPPLowerLayerDownEvent:
  387.         case kPPPAuthenticationStartedEvent:
  388.         case kPPPAuthenticationFinishedEvent:
  389.         case kPPPDCEInitStartedEvent:
  390.         case kPPPDCEInitFinishedEvent:
  391.         case kPPPDCECallStartedEvent:
  392.         case kPPPDCECallFinishedEvent:    
  393.             
  394.             long i = code - kPPPEvent;
  395. //error code comes in cookie for PPP misc events
  396.             if( ((OTResult)cookie) != kOTNoError) DebugStr("\p PPP CSM::NotifyProc -  PPP event failed.; d3.w; d0.w;");
  397. //            else DebugStr("\p PPP CSM::NotifyProc -  PPP event; d3.w;");
  398.         default:;
  399.     }
  400.  
  401. //    (void) SetA5(old_A5);
  402.     (void) SetA4(old_A4);
  403. }
  404.  
  405.  
  406. #pragma mark -
  407.  
  408. //------------------------------------------------------------------------------------
  409. void OpenControlPanel    (OSType folder, OSType fdCreator, OSType  fdType)
  410. //------------------------------------------------------------------------------------
  411. {
  412. #define kFinderSig                 'FNDR'
  413. #define kSystemType             'MACS'
  414. #define kAEOpenSelection        'sope'
  415. #define aeSelectionKeyword        'fsel'
  416.  
  417.     ProcessInfoRec    processInfo;
  418.     ProcessSerialNumber    frontProcess;
  419.     Boolean            sameProcess;
  420.     short            vRefNum;
  421.     long            dirID;
  422.     HFileInfo        pb;
  423.     Str63            filename;
  424.     FSSpec            theSpec;
  425.     AliasHandle        fileAlias, folderAlias;
  426.     OSType            finderSig;
  427.     AEAddressDesc    target;
  428.     AppleEvent        theEvent, ignoreReply;
  429.     AEDescList        fileList;
  430.  
  431.  
  432. // Find the Appropriate folder
  433.     if (FindFolder(kOnSystemDisk, folder, kDontCreateFolder, &vRefNum, &dirID)) return;
  434.  
  435. // Scan folder looking for file
  436.     pb.ioNamePtr   = filename;
  437.     pb.ioVRefNum   = vRefNum;
  438.     pb.ioFVersNum  = 0;
  439.     pb.ioFDirIndex = 1;
  440.     pb.ioDirID     = dirID;
  441.     while (! PBHGetFInfoSync((HParmBlkPtr)&pb)) {
  442. //        if ((pb.ioFlFndrInfo.fdType == fdType) && (pb.ioFlFndrInfo.fdCreator == fdCreator))
  443.          if  (pb.ioFlFndrInfo.fdCreator == fdCreator) 
  444.             goto foundFile;
  445.  
  446.         pb.ioFDirIndex++;
  447.         pb.ioDirID = dirID;
  448.     }
  449.     return;
  450.  
  451. foundFile:
  452.  
  453. // make FSS for file
  454.     if (FSMakeFSSpec(vRefNum, dirID, filename, &theSpec)) return;
  455.  
  456. // Create alias for file
  457.     if (NewAliasMinimal(&theSpec, &fileAlias)) return;
  458.  
  459. //    try to find the Finder's process and bring it to the front
  460.     processInfo.processInfoLength = sizeof(ProcessInfoRec);    // initialize the process info record
  461.     processInfo.processName = nil;
  462.     processInfo.processNumber.highLongOfPSN = 0;
  463.     processInfo.processNumber.lowLongOfPSN = kNoProcess;
  464.     processInfo.processType = 0;
  465.     processInfo.processAppSpec = nil;
  466.  
  467.     while (processInfo.processType != kFinderSig) {            // run thru each of the current processes...
  468.         if (GetNextProcess(&processInfo.processNumber) ||
  469.             GetProcessInformation(&processInfo.processNumber, &processInfo)) return;
  470.  
  471.         if (processInfo.processType == kFinderSig) {        // if this process belongs to the Finder,
  472.  
  473.             if (GetFrontProcess(&frontProcess) ||            //    find out if it's in front
  474.                 SameProcess(&processInfo.processNumber, &frontProcess, &sameProcess)) return;
  475.  
  476.             if (! sameProcess &&                            //    if it isn't, try to bring it to the front
  477.                 SetFrontProcess(&processInfo.processNumber)) return;
  478.         }
  479.     }
  480.  
  481.  
  482. //    send the Finder an AppleEvent to open the file
  483.     finderSig = kSystemType;
  484.     (void) AECreateDesc(typeApplSignature, (Ptr) &finderSig, sizeof(finderSig), &target);        
  485.     (void) AECreateAppleEvent(kFinderSig, kAEOpenSelection, &target, kAutoGenerateReturnID, kAnyTransactionID, &theEvent);
  486.     (void) AEDisposeDesc(&target);
  487.     
  488.     (void) FSMakeFSSpec(vRefNum, dirID, nil, &theSpec);
  489.     (void) NewAliasMinimal(&theSpec, &folderAlias);
  490.     HLock((Handle)folderAlias);
  491.     (void) AEPutParamPtr(&theEvent, keyDirectObject, typeAlias, (Ptr)*folderAlias, (**folderAlias).aliasSize);
  492.     HUnlock((Handle)folderAlias);
  493.     
  494. // Fill w/ file list
  495.     (void) AECreateList(nil, 0, false, &fileList);
  496.     HLock((Handle)fileAlias);
  497.     (void) AEPutPtr(&fileList, 1, typeAlias, (Ptr)*fileAlias, (**fileAlias).aliasSize);
  498.     HUnlock((Handle)fileAlias);
  499.     (void) AEPutParamDesc(&theEvent, aeSelectionKeyword, &fileList);
  500.     DisposHandle((Handle)fileAlias);
  501.     (void) AEDeleteItem(&fileList, 1);
  502.     (void) AEDisposeDesc(&fileList);
  503.     
  504.     (void) AESend(&theEvent, &ignoreReply, kAENoReply+kAENeverInteract, kAEHighPriority,
  505.                     kAEDefaultTimeout, nil, nil);
  506.     (void) AEDisposeDesc(&theEvent);
  507.  
  508.     DisposHandle((Handle)folderAlias);
  509. };
  510.  
  511.  
  512. #pragma mark -
  513. //------------------------------------------------------------------------------------
  514. pascal long  main(unsigned long message, CSM* csm, Rect *statusRect, GrafPtr statusPort)
  515. //------------------------------------------------------------------------------------
  516.  
  517.  {
  518.      long    old_A4 = SetCurrentA4();
  519.     long    result;
  520.     
  521.     result = 0;
  522.     
  523.     switch(message) {
  524.         case sdevInitModule:    
  525.             try {
  526.                 result = (long) new CSM;
  527.                 }
  528.             catch (...)    
  529.             {
  530.                 result = 0;
  531.             }
  532.             break;
  533.             
  534.         case sdevCloseModule:
  535.             delete csm;
  536.             break;
  537.     
  538.         case sdevFeatures:
  539.             result =     ( (1<<sdevWantMouseClicks)    |\
  540.                            (1<<sdevDontAutoTrack)    |\
  541.                            (1<<sdevHasCustomHelp)    |\
  542.                           (1<<sdevKeepModuleLocked) )    ;
  543.             break;
  544.     
  545.  
  546.         case sdevGetDisplayWidth:                
  547.             result = csm->GetDisplayWidth();    
  548.             break;
  549.  
  550.         case sdevPeriodicTickle:    
  551.             result =  csm->Periodic(statusRect, statusPort);    
  552.             break;
  553.             
  554.         case sdevDrawStatus:                            
  555.             result =  csm->Draw(statusRect, statusPort);    
  556.             break;
  557.  
  558.         case sdevMouseClick:                        
  559.             result = csm->MouseDown(statusRect, statusPort);    
  560.             break;
  561.         
  562.         case sdevSaveSettings:
  563.             result = csm->SaveSettings();    
  564.             break;
  565.             
  566.         case sdevShowBalloonHelp:
  567.             result = csm->ShowBalloonHelp();    
  568.             break;
  569.  
  570.     }
  571.     
  572.     (void) SetA4(old_A4);
  573.     return result;
  574. }